home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / asmutil / 68kdis.zip / HEUR.C < prev    next >
C/C++ Source or Header  |  1988-12-03  |  10KB  |  529 lines

  1. /*
  2.  *    SCCS:    @(#)heur.c    1.2    11/2/84    14:17:46
  3.  *    Attempt to guess things about the file.
  4.  *
  5.  ***********************************************************************
  6.  *    This software is copyright of
  7.  *
  8.  *        John M Collins
  9.  *        47 Cedarwood Drive
  10.  *        St Albans
  11.  *        Herts, AL4 0DN
  12.  *        England            +44 727 57267
  13.  *
  14.  *    and is released into the public domain on the following conditions:
  15.  *
  16.  *        1.  No free maintenance will be guaranteed.
  17.  *        2.  Nothing may be based on this software without
  18.  *            acknowledgement, including incorporation of this
  19.  *            notice.
  20.  *
  21.  *    Notwithstanding the above, the author welcomes correspondence and bug
  22.  *    fixes.
  23.  ***********************************************************************
  24.  */
  25.  
  26. #include <stdio.h>
  27. #include <a.out.h>
  28. #include <ldfcn.h>
  29. #include "unc.h"
  30.  
  31. #define    INITDAT    256
  32. #define    INCDAT    128
  33.  
  34. #define    STRSCNT    3
  35. #define    STRECNT    3
  36.  
  37. char    *malloc(), *realloc();
  38.  
  39. void    gette(), getde(), setde(), putte(), putde();
  40. void    nomem();
  41. long    getdw();
  42. symbol    inventsymb();
  43.  
  44. long    endt;
  45. ef_fids    mainfile;
  46.  
  47. /*
  48.  *    Talk about implemented things.....
  49.  */
  50.  
  51. void    unimpl(msg)
  52. char    *msg;
  53. {
  54.     (void) fprintf(stderr, "Warning: handling of \"%s\" not implemented\n", msg);
  55. }
  56.  
  57. /*
  58.  *    Return 1 if string char, otherwise 0.
  59.  */
  60.  
  61. int    possstr(x)
  62. unsigned  x;
  63. {
  64.     if  (x >= ' '  &&  x <= '~')
  65.         return    1;
  66.     if  (x == '\n'  ||  x == '\t')
  67.         return    1;
  68.     return    0;
  69. }
  70.  
  71. /*
  72.  *    Guess things about data files.
  73.  */
  74.  
  75. void    intudat(fid)
  76. ef_fid  fid;
  77. {
  78.     register  int    i, j;
  79.     int    lt, input, invcnt;
  80.     long    offs, soffs, endd;
  81.     d_entry    fdat;
  82.     unsigned  char    *inbuf;
  83.     int    ibsize;
  84.     
  85.     inbuf = (unsigned  char *)malloc(INITDAT);
  86.     if  (inbuf == NULL)
  87.         nomem();
  88.     ibsize = INITDAT;
  89.     
  90.     offs = fid->ef_dbase;
  91.     endd = fid->ef_bbase;
  92.  
  93.     while  (offs < endd)  {
  94.         getde(fid, offs, &fdat);
  95.         if  (fdat.d_type != D_BYTE)  {
  96.             offs += fdat.d_lng;
  97.             continue;
  98.         }
  99.         
  100.         /*
  101.          *    Looks like general data.  Read in as much as possible.
  102.          */
  103.         
  104.         input = 0;
  105.         soffs = offs;
  106.         do  {
  107.             if  (input >= ibsize)  {
  108.                 ibsize += INCDAT;
  109.                 inbuf = (unsigned  char *)
  110.                     realloc((char *)inbuf, (unsigned)ibsize);
  111.                 if  (inbuf == NULL)
  112.                     nomem();
  113.             }
  114.             inbuf[input++] = fdat.d_contents;
  115.             offs++;
  116.             if  (offs >= endd)
  117.                 break;
  118.             getde(fid, offs, &fdat);
  119.         }  while  (fdat.d_type == D_BYTE && fdat.d_lab == NULL);
  120.         
  121.         /*
  122.          *    Now split up the data.
  123.          */
  124.         
  125.         for  (i = 0;  i < input;  )  {
  126.             
  127.             /*
  128.              *    Might be a string.
  129.              */
  130.             
  131.             if  (possstr(inbuf[i]))  {
  132.                 lt = input;
  133.                 if  (i + STRSCNT < lt)
  134.                     lt = i + STRSCNT;
  135.                 for  (j = i + 1;  j < lt;  j++)  {
  136.                     if  (inbuf[j] == '\0')
  137.                         break;
  138.                     if  (!possstr(inbuf[j]))
  139.                         goto  notstr;
  140.                 }
  141.                 
  142.                 /*
  143.                  *    Looks like a string then.
  144.                  */
  145.                 
  146.                 invcnt = 0;
  147.                 for  (j = i + 1; j < input;  j++)  {
  148.                     if  (inbuf[j] == '\0')  {
  149.                         j++;
  150.                         break;
  151.                     }
  152.                     if  (possstr(inbuf[j]))
  153.                         invcnt = 0;
  154.                     else  {
  155.                         invcnt++;
  156.                         if  (invcnt >= STRECNT)  {
  157.                             j -= invcnt - 1;
  158.                             break;
  159.                         }
  160.                     }
  161.                 }
  162.  
  163.                 setde(fid,
  164.                       soffs+i,
  165.                       (unsigned)(inbuf[j-1]=='\0'?D_ASCZ:D_ASC),
  166.                       j - i);
  167.                 for  (i++;  i < j;  i++)
  168.                     setde(fid, soffs+i, D_CONT, 1); 
  169.                 continue;
  170.             }
  171.  
  172. notstr:
  173.             /*
  174.              *    If on odd boundary, treat as a byte.
  175.              */
  176.             
  177.             if  ((soffs + i) & 1  ||  i + 1 >= input)  {
  178.                 setde(fid, soffs + i, D_BYTE, 1);
  179.                 i++;
  180.                 continue;
  181.             }
  182.  
  183.             /*
  184.              *    Treat as longs unless not enough.
  185.              */
  186.             
  187.             if  (i + 3 >= input)  {
  188.                 setde(fid, soffs + i, D_WORD, 2);
  189.                 setde(fid, soffs + i + 1, D_CONT, -1);
  190.                 i += 2;
  191.                 continue;
  192.             }
  193.  
  194.             /*
  195.              *    Treat as a long but mark changable.
  196.              */
  197.             
  198.             setde(fid, soffs + i, D_LONG, 4);
  199.             for  (j = 1;  j < 4;  j++)
  200.                 setde(fid, soffs + i + j, D_CONT, -j);
  201.             i += 4;
  202.         }
  203.     }
  204.     free((char *)inbuf);
  205.     
  206.     /*
  207.      *    Now zap bss segment.
  208.      */
  209.     
  210.     offs = fid->ef_bbase;
  211.     endd = fid->ef_end;
  212.  
  213.     while  (offs < endd)  {
  214.         getde(fid, offs, &fdat);
  215.         if  (fdat.d_type != D_BYTE)  {
  216.             offs += fdat.d_lng;
  217.             continue;
  218.         }
  219.  
  220.         soffs = offs;
  221.         do  {
  222.             offs++;
  223.             if  (offs >= endd)
  224.                 break;
  225.             getde(fid, offs, &fdat);
  226.         }  while  (fdat.d_type == D_BYTE && fdat.d_lab == NULL);
  227.         
  228.         setde(fid, soffs, D_BYTE, (int)(offs-soffs));
  229.         for  (i = -1, soffs++;  soffs < offs; i--, soffs++)
  230.             setde(fid, soffs, D_CONT, i); 
  231.     }
  232. }
  233.  
  234. /*
  235.  *    For non relocatable files, try to identify address pointers in
  236.  *    the data.
  237.  */
  238.  
  239. void    inturdat(fid)
  240. ef_fid    fid;
  241. {
  242.     register  long    offs = fid->ef_dbase;
  243.     register  int    i;
  244.     register  symbol  ds;
  245.     long  endd = fid->ef_bbase;
  246.     long  cont;
  247.     d_entry    dent, refdent;
  248.  
  249.     while  (offs < endd)  {
  250.         getde(fid, offs, &dent);
  251.         if  (dent.d_type != D_LONG)
  252.             goto  endit;
  253.         cont = getdw(fid, offs, R_LONG);
  254.         if  (cont < fid->ef_dbase || cont > fid->ef_end)
  255.             goto  endit;
  256.         getde(fid, cont, &refdent);
  257.         if  (refdent.d_type == D_CONT)  {
  258.             d_entry    pdent;
  259.             int    siz;
  260.             
  261.             if  (refdent.d_lng >= 0)
  262.                 goto  endit;
  263.             getde(fid, cont+refdent.d_lng, &pdent);
  264.             i = -refdent.d_lng;
  265.             refdent.d_lng += pdent.d_lng;
  266.             pdent.d_lng = i;
  267.             if  (pdent.d_type == D_LONG  &&  i == 2)
  268.                 siz = D_WORD;
  269.             else
  270.                 siz = D_BYTE;
  271.             refdent.d_type = siz;
  272.             pdent.d_type = siz;
  273.             putde(fid, cont - i, &pdent);
  274.             for  (i = 1;  i < refdent.d_lng;  i++)
  275.                 setde(fid, cont+i, D_CONT, -i);
  276.         }
  277.         if  ((ds = refdent.d_lab) == NULL)  {
  278.             if  (cont >= fid->ef_bbase)  {
  279.                 ds = inventsymb("BS");
  280.                 ds->s_type = S_BSS;
  281.             }
  282.             else  {
  283.                 ds = inventsymb("DS");
  284.                 ds->s_type = S_DATA;
  285.             }
  286.             ds->s_value = cont;
  287.             refdent.d_lab = ds;
  288.             putde(fid, cont, &refdent);
  289.         }
  290.         else
  291.             ds->s_used++;
  292.         dent.d_type = D_ADDR;
  293.         dent.d_relsymb = ds;
  294.         dent.d_rptr = ds->s_type;
  295.         putde(fid, offs, &dent);
  296.         for  (i = 1;  i < 4;  i++)
  297.             setde(fid, offs+i, D_CONT, 1);
  298. endit:
  299.         offs += dent.d_lng;
  300.     }
  301. }
  302.  
  303. /*
  304.  *    Recursively follow through the code, stopping at unconditional
  305.  *    branches and invalid instructions.
  306.  */
  307.  
  308. void    follseq(pos)
  309. long    pos;
  310. {
  311.     t_entry    tent;
  312.     int    lng;
  313.     long    npos;
  314.  
  315.     while  (pos < endt)  {
  316.         gette(&mainfile, pos, &tent);
  317.         if  (tent.t_amap)    /*  Been here  */
  318.             return;
  319.         tent.t_amap = 1;
  320.         lng = findinst(&tent, pos);
  321.         npos = pos + lng*2;
  322.         if  (npos > endt)  {
  323.             tent.t_vins = 0;
  324.             tent.t_lng = 1;
  325.             tent.t_type = T_UNKNOWN;
  326.             lng = 0;
  327.             npos = endt;
  328.         }
  329.         putte(&mainfile, pos, &tent);
  330.         pos = npos;
  331.         
  332.         if  (lng <= 0)
  333.             return;
  334.  
  335.         switch  (tent.t_bchtyp)  {
  336.         case  T_UNBR:
  337.             if  (tent.t_relsymb == NULL)
  338.                 return;
  339.             pos = tent.t_relsymb->s_value;
  340.             continue;
  341.         case  T_JSR:
  342.             if  (tent.t_relsymb != NULL)
  343.                 follseq(tent.t_relsymb->s_value);
  344.             continue;
  345.         case  T_CONDBR:
  346.             follseq(tent.t_relsymb->s_value);
  347.         default:
  348.             continue;
  349.         }
  350.     }
  351. }
  352.             
  353.             
  354. /*
  355.  *    Try to work out things about text files.
  356.  */
  357.  
  358. void    intutext()
  359. {
  360.     long    pos;
  361.     t_entry    tent;
  362.     int    lng;
  363.     
  364.     endt = mainfile.ef_tbase + mainfile.ef_tsize;
  365.     pos = mainfile.ef_entry;
  366. nextv:
  367.     for  (;  pos < endt;)  {
  368.         gette(&mainfile, pos, &tent);
  369.         if  (!tent.t_amap && tent.t_vins)  {
  370.             follseq(pos);
  371.             pos += 2;
  372.             goto  nextiv;
  373.         }
  374.         pos += tent.t_lng * 2;
  375.         if  (tent.t_bchtyp == T_UNBR)
  376.             goto  nextiv;
  377.     }
  378.     goto    dorest;
  379. nextiv:
  380.     for  (;  pos < endt;  pos += 2)  {
  381.         gette(&mainfile, pos, &tent);
  382.         if  (tent.t_bdest)
  383.             goto  nextv;
  384.     }
  385. dorest:
  386.     /*
  387.      *    Deal with unmapped instructions.
  388.      */
  389.     
  390.      for  (pos = mainfile.ef_tbase;  pos < endt;)  {
  391.         gette(&mainfile, pos, &tent);
  392.         switch  (tent.t_type)  {
  393.         case  T_BEGIN:
  394.             pos += tent.t_lng * 2;
  395.             continue;
  396.         case  T_UNKNOWN:
  397.             if  (tent.t_vins)  {
  398.                 lng = findinst(&tent, pos);
  399.                 putte(&mainfile, pos, &tent);
  400.                 if  (lng > 0)  {
  401.                     pos += lng * 2;
  402.                     continue;
  403.                 }
  404.             }
  405.         default:
  406.             pos += 2;
  407.             continue;
  408.         }
  409.     }
  410. }
  411.  
  412. /*
  413.  *    Invent local symbols.
  414.  */
  415.  
  416. void    intlsym()
  417. {
  418.     long    bpos, epos, hiref, hipos;
  419.     unsigned  llnum;
  420.     t_entry    tent;
  421.     register  symbol  tl;
  422.     
  423.     endt = mainfile.ef_tbase + mainfile.ef_tsize;
  424.     epos = mainfile.ef_entry;
  425.     for  (;;)  {
  426.         bpos = epos;
  427.         hiref = bpos;
  428.         if  (epos >= endt)
  429.             return;
  430.         gette(&mainfile, epos, &tent);
  431.         epos += tent.t_lng * 2;
  432.         for  (;  epos < endt;)  {
  433.             gette(&mainfile, epos, &tent);
  434.             if  (tent.t_gbdest  ||  tent.t_dref)
  435.                 break;
  436.             if  (tent.t_reflo < bpos)
  437.                 break;
  438.             if  (tent.t_refhi > hiref)  {
  439.                 hiref = tent.t_